home *** CD-ROM | disk | FTP | other *** search
- /*
- EPSHeader
-
- File: tagio.c
- Author: J. Kercheval
- Created: Wed, 07/17/1991 21:48:14
- */
- /*
- EPSRevision History
-
- J. Kercheval Sun, 08/18/1991 20:49:44 add fill_buffer()
- J. Kercheval Tue, 09/03/1991 23:25:13 add buffer_offset to fill_buffer()
- J. Kercheval Thu, 09/05/1991 20:13:01 add MergeFile()
- J. Kercheval Tue, 09/10/1991 23:55:47 add calls to external_cleanup() when exiting
- J. Kercheval Tue, 09/17/1991 19:41:16 add support for case_sensitive flag
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <io.h>
-
- #include "tagio.h"
- #include "log.h"
-
-
- /* external_cleanup() is used on exit(1) for internal error */
- extern void external_cleanup(void);
-
-
- /*----------------------------------------------------------------------------
- *
- * FillBuffer() fills the passed buffer parameter with bufsize characters
- * (or as many as are available) and places and null character '\0' at the
- * end of the buffer. This routine returns TRUE if successful and FALSE if
- * eof(infile) is true. Note: if a bufsize parameter is passed and the read
- * is successful for bufsize characters, then buffer[bufsize] will be
- * overwritten with the null character. Do not pass a bufsize the maximum
- * size of the buffer. This null terminated buffering scheme assumes the
- * source file has no null character embedded within it.
- *
- ---------------------------------------------------------------------------*/
-
- BOOLEAN FillBuffer(FILE * infile, char *buffer, long int bufsize)
- {
- long int size;
-
- /* init buffer */
- *buffer = '\0';
-
- /* return if end of file */
- if (feof(infile))
- return FALSE;
-
- /* read the buffer from the file */
- size = (long int) fread((void *) buffer, (size_t) sizeof(unsigned char),
- (size_t) bufsize, infile);
-
- /* place the end of buffer mark and return success */
- buffer[size] = '\0';
- return TRUE;
- }
-
-
- /*----------------------------------------------------------------------------
- *
- * GetLine will read a line not to exceed n-1 chars from f and will return
- * true if any characters parsed
- *
- ---------------------------------------------------------------------------*/
-
- BOOLEAN GetLine(FILE * f, char *line, int n)
- {
- int i; /* looping variable (size of line) */
- char c; /* temporary character variable */
-
- /* check for end of file */
- if (feof(f))
- return FALSE;
-
- for (i = 0, c = '\0'; !feof(f) && c != '\n' && i < n - 1; i++) {
-
- /* get next char */
- c = (char) fgetc(f);
-
- /* check for end of line due to n-1th character read */
- if (i == n - 2) {
- log_message("# getline() -- long line encountered - truncating");
- do {
- c = (char) fgetc(f);
- } while (!feof(f) && c != '\n');
- }
-
- /* write the character to the line */
- line[i] = c;
- }
-
- /* zero length string and end of file return FALSE */
- if (feof(f) && i == 1)
- return FALSE;
-
- /* write end of line and return */
- line[i - 1] = '\0';
- return TRUE;
- }
-
-
- /*----------------------------------------------------------------------------
- *
- * OutputTag() places the tag in the correct format into the output stream
- *
- ---------------------------------------------------------------------------*/
-
- void OutputTag(FILE * outfile, char *line, char *symbol, char *infname,
- long int line_number, long int char_number, Flags * flags)
- {
- /* epsilon style output */
- if (flags->oe) {
- fprintf(outfile, "%s;%s;%ld\n", symbol, infname, char_number);
- return;
- }
-
- /* GNU style output */
- if (flags->og) {
- fprintf(outfile, "%s\t%s\t/^%s$/\n", symbol, infname, line);
- return;
- }
-
- /* spaces delimited output */
- if (flags->os) {
- fprintf(outfile, "%s %s %ld\n", symbol, infname, line_number);
- return;
- }
-
- /* MicroSoft Error format */
- if (flags->om) {
- fprintf(outfile, "%s %s(%ld)\n", symbol, infname, line_number);
- return;
- }
-
- /* not reached */
- log_message("# OutputTag -- internal error - continuing");
- return;
- }
-
-
- /*----------------------------------------------------------------------------
- *
- * MergeFile() will take the temporary file and merge it into the potentially
- * existing tag file. During the merge, any tags from the input files which
- * were processed during this session will be deleted from the tag file to
- * prevent innaccurate tagging information.
- *
- ---------------------------------------------------------------------------*/
-
- #define MAX_TAGFILE_LINE_LENGTH 4096
- #define MAXPATH 80
-
- void MergeFile(char *input_filename, char *output_filename,
- ArgList arglist, Flags * flags)
- {
- FILE *input_stream; /* file pointer used for input */
- FILE *new_tag_stream; /* file pointer used by new tag stream */
- FILE *output_stream; /* file pointer used for output */
-
- char line1[MAX_TAGFILE_LINE_LENGTH]; /* line for new tag file */
- char line2[MAX_TAGFILE_LINE_LENGTH]; /* line for old tag file */
- char tag_filename[MAXPATH]; /* intermediate used to purge old tags */
-
- char delim[] = " \t;("; /* list of valid delimiters for tag format */
-
- char *tmp_filename; /* intermediate file name */
-
- char *token_start; /* pointer to interesting tokens on purge */
- int token_length; /* length of token at token_start */
-
- int compare; /* the results of a stricmp() */
-
- BOOLEAN file1ret; /* true while new tag file in not at EOF */
- BOOLEAN file2ret; /* true while old tag file in not at EOF */
-
- if (access(output_filename, 00)) {
-
- /* open the new tags file for read */
- if ((new_tag_stream = fopen(input_filename, "r")) ==
- (FILE *) NULL) {
- log_message("# MergeFile() -- error opening input file");
- external_cleanup();
- exit(1);
- }
-
- /* open the tag output file for write */
- if ((output_stream = fopen(output_filename, "w")) ==
- (FILE *) NULL) {
- log_message("# MergeFile() -- error opening tag file");
- external_cleanup();
- exit(1);
- }
-
- /* the old tag output file doesn't exist yet, just copy it over */
- while (GetLine(new_tag_stream, line1, MAX_TAGFILE_LINE_LENGTH)) {
- fprintf(output_stream, "%s\n", line1);
- }
-
- /* close the files */
- fclose(new_tag_stream);
- fclose(output_stream);
- }
- else {
-
- /* create the required temporary file name */
- tmp_filename = tempnam(".\\", "tg");
-
- /* open the old tag file */
- if ((input_stream = fopen(output_filename, "r")) ==
- (FILE *) NULL) {
- log_message("# MergeFile() -- error opening output file");
- external_cleanup();
- exit(1);
- }
-
- /* open the temporary file */
- if ((output_stream = fopen(tmp_filename, "w")) ==
- (FILE *) NULL) {
- log_message("# MergeFile() -- error opening temporary file");
- external_cleanup();
- exit(1);
- }
-
- /* copy the output file to a temporary file and at the same time
- * remove the old tags */
- while (GetLine(input_stream, line1, MAX_TAGFILE_LINE_LENGTH)) {
-
- /* only output the line if the line is non zero in length */
- if (line1[0] != '\0') {
-
- /* pass the first token on the line */
- token_start = strpbrk(line1, delim);
- while (strspn(token_start, delim)) {
- token_start++;
- }
-
- /* get the length of the second token on the line */
- token_length = strcspn(token_start, delim);
-
- /* copy the name to a temporary variable */
- strncpy(tag_filename, token_start, token_length);
- tag_filename[token_length] = '\0';
-
- /* if the token is not in argInput then output it */
- if (!ArgIsMember(arglist, tag_filename)) {
- fprintf(output_stream, "%s\n", line1);
- }
- }
- }
-
- /* close the open files */
- fclose(input_stream);
- fclose(output_stream);
-
- /* remove the old tag file */
- remove(output_filename);
-
- /* open the temporary file for read */
- if ((input_stream = fopen(tmp_filename, "r")) ==
- (FILE *) NULL) {
- log_message("# MergeFile() -- error opening input file");
- external_cleanup();
- exit(1);
- }
-
- /* open the new tags file for read */
- if ((new_tag_stream = fopen(input_filename, "r")) ==
- (FILE *) NULL) {
- log_message("# MergeFile() -- error opening input file");
- external_cleanup();
- exit(1);
- }
-
- /* open the tag output file for write */
- if ((output_stream = fopen(output_filename, "w")) ==
- (FILE *) NULL) {
- log_message("# MergeFile() -- error opening tag file");
- external_cleanup();
- exit(1);
- }
-
- /* merge the new tags in with the old tags */
- file1ret = GetLine(new_tag_stream, line1, MAX_TAGFILE_LINE_LENGTH);
- file2ret = GetLine(input_stream, line2, MAX_TAGFILE_LINE_LENGTH);
- while (file1ret || file2ret) {
-
- /* compare the lines and output in ascending order. If the
- * command line specified no sorting then place the new tags
- * first and then the old tags. This will result in slightly
- * better performance for non-sorted tag finding algorithms
- * assuming the last files tagged are the most likely to be used
- * in the future */
- if (file1ret && file2ret) {
- if (flags->sort_tags) {
-
- /* determine the sort order */
- if (flags->case_sensitive)
- compare = strcmp(line1, line2);
- else
- compare = stricmp(line1, line2);
-
- /* if the new tag is less than or equal to the old tag
- * then output the new tag */
- if (compare <= 0) {
-
- /* output the new tag and get another line */
- fprintf(output_stream, "%s\n", line1);
- file1ret = GetLine(new_tag_stream, line1,
- MAX_TAGFILE_LINE_LENGTH);
- }
- else {
-
- /* output the old tag and get another line */
- fprintf(output_stream, "%s\n", line2);
- file2ret = GetLine(input_stream, line2,
- MAX_TAGFILE_LINE_LENGTH);
- }
- }
- else {
-
- /* just output from the new tag file and get another line */
- fprintf(output_stream, "%s\n", line1);
- file1ret = GetLine(new_tag_stream, line1,
- MAX_TAGFILE_LINE_LENGTH);
- }
- }
- else {
- if (file2ret) {
-
- /* new tag file is empty, just output line2, and get the
- * next line in old tag file */
- fprintf(output_stream, "%s\n", line2);
- file2ret = GetLine(input_stream, line2,
- MAX_TAGFILE_LINE_LENGTH);
- }
- else {
-
- /* old tag file is empty, just output line1, and get the
- * next line in new tag file */
- fprintf(output_stream, "%s\n", line1);
- file1ret = GetLine(new_tag_stream, line1,
- MAX_TAGFILE_LINE_LENGTH);
- }
- }
- }
-
- /* close the open files */
- fclose(input_stream);
- fclose(new_tag_stream);
- fclose(output_stream);
-
- /* remove the temporary file and free tmp_filename memory */
- remove(tmp_filename);
- free(tmp_filename);
- }
- }
-